package com.ruoyi.system.service.impl;

import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.mapper.TopicChangeRequestMapper;
import com.ruoyi.system.mapper.ApplicationMapper;
import com.ruoyi.system.mapper.TopicMapper;
import com.ruoyi.system.mapper.TeacherInfoMapper;
import com.ruoyi.system.domain.TopicChangeRequest;
import com.ruoyi.system.domain.Application;
import com.ruoyi.system.domain.Topic;
import com.ruoyi.system.service.ITopicChangeRequestService;
import com.ruoyi.common.exception.ServiceException;

/**
 * 选题变更申请Service业务层处理
 *
 * @author ltr
 * @date 2024-11-16
 */
@Service
public class TopicChangeRequestServiceImpl implements ITopicChangeRequestService
{
    @Autowired
    private TopicChangeRequestMapper topicChangeRequestMapper;

    @Autowired
    private ApplicationMapper applicationMapper;

    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private TeacherInfoMapper teacherInfoMapper;

    /**
     * 查询选题变更申请
     *
     * @param requestId 选题变更申请主键
     * @return 选题变更申请
     */
    @Override
    public TopicChangeRequest selectTopicChangeRequestByRequestId(Long requestId)
    {
        return topicChangeRequestMapper.selectTopicChangeRequestByRequestId(requestId);
    }

    /**
     * 查询选题变更申请列表（管理员使用）
     *
     * @param topicChangeRequest 选题变更申请
     * @return 选题变更申请
     */
    @Override
    public List<TopicChangeRequest> selectTopicChangeRequestList(TopicChangeRequest topicChangeRequest)
    {
        return topicChangeRequestMapper.selectTopicChangeRequestList(topicChangeRequest);
    }

    /**
     * 查询学生的变更申请列表
     *
     * @param studentId 学生ID
     * @return 选题变更申请集合
     */
    @Override
    public List<TopicChangeRequest> selectChangeRequestListByStudentId(Long studentId)
    {
        return topicChangeRequestMapper.selectChangeRequestListByStudentId(studentId);
    }

    /**
     * 查询原教师需要审核的变更申请列表
     *
     * @param teacherId 教师ID
     * @return 选题变更申请集合
     */
    @Override
    public List<TopicChangeRequest> selectPendingRequestsForOldTeacher(Long teacherId)
    {
        return topicChangeRequestMapper.selectPendingRequestsForOldTeacher(teacherId);
    }

    /**
     * 查询新教师需要审核的变更申请列表
     *
     * @param teacherId 教师ID
     * @return 选题变更申请集合
     */
    @Override
    public List<TopicChangeRequest> selectPendingRequestsForNewTeacher(Long teacherId)
    {
        return topicChangeRequestMapper.selectPendingRequestsForNewTeacher(teacherId);
    }

    /**
     * 查询教师相关的所有变更申请列表（作为原教师或新教师）
     *
     * @param teacherId 教师ID
     * @return 选题变更申请集合
     */
    @Override
    public List<TopicChangeRequest> selectChangeRequestListByTeacherId(Long teacherId)
    {
        return topicChangeRequestMapper.selectChangeRequestListByTeacherId(teacherId);
    }

    /**
     * 学生提交选题变更申请
     *
     * @param topicChangeRequest 选题变更申请
     * @return 结果
     */
    @Override
    @Transactional
    public int submitChangeRequest(TopicChangeRequest topicChangeRequest)
    {
        // 1. 检查学生是否已被录取
        Application accepted = applicationMapper.selectAcceptedApplicationByStudentId(
                topicChangeRequest.getStudentId());
        if (accepted == null)
        {
            throw new ServiceException("您还未被任何题目录取，无法申请变更");
        }

        // 2. 检查原题目ID是否与当前录取的题目一致
        if (!accepted.getTopicId().equals(topicChangeRequest.getOldTopicId()))
        {
            throw new ServiceException("原题目信息不正确，请刷新页面后重试");
        }

        // 3. 检查是否有待处理的变更申请
        int pendingCount = topicChangeRequestMapper.checkStudentPendingRequest(
                topicChangeRequest.getStudentId());
        if (pendingCount > 0)
        {
            throw new ServiceException("您有待处理的变更申请，请等待审核完成后再提交新申请");
        }

        // 4. 检查新题目是否存在
        Topic newTopic = topicMapper.selectTopicByTopicId(topicChangeRequest.getNewTopicId());
        if (newTopic == null)
        {
            throw new ServiceException("新题目不存在");
        }

        // 5. 检查新题目是否还有名额
        if (newTopic.getCurrentStudents() >= newTopic.getMaxStudents())
        {
            throw new ServiceException("新题目名额已满");
        }

        // 6. 检查新题目状态是否开放
        if (!"开放".equals(newTopic.getStatus()))
        {
            throw new ServiceException("新题目当前不开放申请");
        }

        // 7. 检查新题目审核状态
        if (!"已通过".equals(newTopic.getAuditStatus()))
        {
            throw new ServiceException("新题目还未通过审核");
        }

        // 8. 检查新旧题目是否相同
        if (topicChangeRequest.getOldTopicId().equals(topicChangeRequest.getNewTopicId()))
        {
            throw new ServiceException("新旧题目不能相同");
        }

        // 9. 变更理由必填
        if (topicChangeRequest.getChangeReason() == null ||
                topicChangeRequest.getChangeReason().trim().isEmpty())
        {
            throw new ServiceException("请填写变更理由");
        }

        // 10. 插入变更申请
        topicChangeRequest.setStatus("待审核");
        topicChangeRequest.setCreateTime(DateUtils.getNowDate());

        return topicChangeRequestMapper.insertTopicChangeRequest(topicChangeRequest);
    }

    /**
     * 学生取消选题变更申请
     *
     * @param requestId 申请ID
     * @param studentId 学生ID
     * @return 结果
     */
    @Override
    public int cancelChangeRequest(Long requestId, Long studentId)
    {
        // 1. 检查申请是否属于该学生
        if (topicChangeRequestMapper.checkRequestOwner(requestId, studentId) == 0)
        {
            throw new ServiceException("无权取消该申请");
        }

        // 2. 检查申请状态是否可以取消
        TopicChangeRequest request = topicChangeRequestMapper.selectTopicChangeRequestByRequestId(requestId);
        if (request == null)
        {
            throw new ServiceException("申请不存在");
        }
        if (!"待审核".equals(request.getStatus()))
        {
            throw new ServiceException("该申请当前状态无法取消");
        }

        // 3. 取消申请
        return topicChangeRequestMapper.cancelChangeRequest(requestId);
    }

    /**
     * 原教师审核变更申请
     *
     * @param requestId 申请ID
     * @param teacherId 教师ID
     * @param opinion 审核意见（同意/拒绝）
     * @param reason 意见说明
     * @return 结果
     */
    @Override
    @Transactional
    public int reviewByOldTeacher(Long requestId, Long teacherId, String opinion, String reason)
    {
        // 1. 检查申请是否属于该教师的题目
        if (topicChangeRequestMapper.checkRequestOldTeacher(requestId, teacherId) == 0)
        {
            throw new ServiceException("无权审核该申请");
        }

        // 2. 检查申请状态
        TopicChangeRequest request = topicChangeRequestMapper.selectTopicChangeRequestByRequestId(requestId);
        if (request == null)
        {
            throw new ServiceException("申请不存在");
        }
        if (!"待审核".equals(request.getStatus()))
        {
            throw new ServiceException("该申请已被处理");
        }
        if (request.getOldTeacherOpinion() != null)
        {
            throw new ServiceException("您已审核过该申请");
        }

        // 3. 验证审核意见
        if (!"同意".equals(opinion) && !"拒绝".equals(opinion))
        {
            throw new ServiceException("审核意见只能是「同意」或「拒绝」");
        }

        // 4. 更新原教师审核意见
        int result = topicChangeRequestMapper.reviewByOldTeacher(requestId, opinion, reason);

        // 5. 如果原教师拒绝，直接设置最终状态为已拒绝
        if ("拒绝".equals(opinion))
        {
            topicChangeRequestMapper.updateFinalStatus(requestId, "已拒绝");
        }
        // 6. 如果原教师同意，检查是否为同一教师换题
        else if ("同意".equals(opinion))
        {
            // 获取原题目和新题目的教师ID
            Topic oldTopic = topicMapper.selectTopicByTopicId(request.getOldTopicId());
            Topic newTopic = topicMapper.selectTopicByTopicId(request.getNewTopicId());

            // 如果是同一个教师，直接执行换题操作
            if (oldTopic.getTeacherId().equals(newTopic.getTeacherId()))
            {
                // 自动设置新教师意见为同意
                topicChangeRequestMapper.reviewByNewTeacher(requestId, "同意", "同一教师，自动同意");

                // 执行换题操作
                executeTopicChange(request);

                // 设置最终状态为已通过
                topicChangeRequestMapper.updateFinalStatus(requestId, "已通过");
            }
        }

        return result;
    }

    /**
     * 新教师审核变更申请
     *
     * @param requestId 申请ID
     * @param teacherId 教师ID
     * @param opinion 审核意见（同意/拒绝）
     * @param reason 意见说明
     * @return 结果
     */
    @Override
    @Transactional
    public int reviewByNewTeacher(Long requestId, Long teacherId, String opinion, String reason)
    {
        // 1. 检查申请是否属于该教师的题目
        if (topicChangeRequestMapper.checkRequestNewTeacher(requestId, teacherId) == 0)
        {
            throw new ServiceException("无权审核该申请");
        }

        // 2. 检查申请状态
        TopicChangeRequest request = topicChangeRequestMapper.selectTopicChangeRequestByRequestId(requestId);
        if (request == null)
        {
            throw new ServiceException("申请不存在");
        }
        if (!"待审核".equals(request.getStatus()))
        {
            throw new ServiceException("该申请已被处理");
        }

        // 3. 检查原教师是否已同意
        if (!"同意".equals(request.getOldTeacherOpinion()))
        {
            throw new ServiceException("原教师还未同意，无法审核");
        }

        // 4. 检查新教师是否已审核
        if (request.getNewTeacherOpinion() != null)
        {
            throw new ServiceException("您已审核过该申请");
        }

        // 5. 验证审核意见
        if (!"同意".equals(opinion) && !"拒绝".equals(opinion))
        {
            throw new ServiceException("审核意见只能是「同意」或「拒绝」");
        }

        // 6. 更新新教师审核意见
        int result = topicChangeRequestMapper.reviewByNewTeacher(requestId, opinion, reason);

        // 7. 处理最终状态
        if ("拒绝".equals(opinion))
        {
            // 新教师拒绝，设置最终状态为已拒绝
            topicChangeRequestMapper.updateFinalStatus(requestId, "已拒绝");
        }
        else if ("同意".equals(opinion))
        {
            // 两位教师都同意，执行换题操作
            executeTopicChange(request);
            topicChangeRequestMapper.updateFinalStatus(requestId, "已通过");
        }

        return result;
    }

    /**
     * 执行换题操作（私有方法）
     *
     * @param request 变更申请
     */
    private void executeTopicChange(TopicChangeRequest request)
    {
        // 1. 获取学生当前的录取记录
        Application oldApplication = applicationMapper.selectAcceptedApplicationByStudentId(request.getStudentId());
        if (oldApplication == null)
        {
            throw new ServiceException("未找到学生的录取记录");
        }

        // 2. 检查新题目是否还有名额
        Topic newTopic = topicMapper.selectTopicByTopicId(request.getNewTopicId());
        if (newTopic == null)
        {
            throw new ServiceException("新题目不存在");
        }
        if (newTopic.getCurrentStudents() >= newTopic.getMaxStudents())
        {
            throw new ServiceException("新题目名额已满，变更失败");
        }

        // 3. 获取原题目信息
        Topic oldTopic = topicMapper.selectTopicByTopicId(request.getOldTopicId());
        if (oldTopic == null)
        {
            throw new ServiceException("原题目不存在");
        }

        // 4. 将原申请状态设置为已失效
        applicationMapper.updateApplicationStatus(oldApplication.getApplicationId(), "已失效");

        // 5. 原题目学生数 -1
        topicMapper.updateTopicCurrentStudents(request.getOldTopicId(), -1);

        // 6. 原教师指导学生数 -1
        teacherInfoMapper.updateTeacherCurrentStudents(oldTopic.getTeacherId(), -1);

        // 7. 如果原题目原本是已满状态，现在有名额了，更新为开放状态
        Topic updatedOldTopic = topicMapper.selectTopicByTopicId(request.getOldTopicId());
        if ("已满".equals(updatedOldTopic.getStatus()) &&
                updatedOldTopic.getCurrentStudents() < updatedOldTopic.getMaxStudents())
        {
            updatedOldTopic.setStatus("开放");
            topicMapper.updateTopic(updatedOldTopic);
        }

        // 8. 创建新的录取记录
        Application newApplication = new Application();
        newApplication.setStudentId(request.getStudentId());
        newApplication.setTopicId(request.getNewTopicId());
        newApplication.setPriority(oldApplication.getPriority()); // 保持原优先级
        newApplication.setStatus("已录取");
        newApplication.setApplyReason(request.getChangeReason()); // 使用换题申请时填写的变更理由
        newApplication.setReviewResult("录取");
        newApplication.setReviewReason("换题申请通过");
        newApplication.setReviewTime(DateUtils.getNowDate());
        newApplication.setReviewBy("系统自动");
        newApplication.setCreateTime(DateUtils.getNowDate());
        newApplication.setCreateBy("系统自动");
        applicationMapper.insertApplication(newApplication);

        // 9. 新题目学生数 +1
        topicMapper.updateTopicCurrentStudents(request.getNewTopicId(), 1);

        // 10. 新教师指导学生数 +1
        teacherInfoMapper.updateTeacherCurrentStudents(newTopic.getTeacherId(), 1);

        // 11. 如果新题目满员，更新状态为已满
        Topic updatedNewTopic = topicMapper.selectTopicByTopicId(request.getNewTopicId());
        if (updatedNewTopic.getCurrentStudents() >= updatedNewTopic.getMaxStudents())
        {
            updatedNewTopic.setStatus("已满");
            topicMapper.updateTopic(updatedNewTopic);
        }
    }

    /**
     * 批量删除选题变更申请（管理员）
     *
     * @param requestIds 需要删除的选题变更申请主键
     * @return 结果
     */
    @Override
    public int deleteTopicChangeRequestByRequestIds(Long[] requestIds)
    {
        return topicChangeRequestMapper.deleteTopicChangeRequestByRequestIds(requestIds);
    }

    /**
     * 删除选题变更申请信息（管理员）
     *
     * @param requestId 选题变更申请主键
     * @return 结果
     */
    @Override
    public int deleteTopicChangeRequestByRequestId(Long requestId)
    {
        return topicChangeRequestMapper.deleteTopicChangeRequestByRequestId(requestId);
    }

    /**
     * 检查学生是否可以提交变更申请
     *
     * @param studentId 学生ID
     * @return 是否可以提交
     */
    @Override
    public boolean canStudentSubmitChangeRequest(Long studentId)
    {
        // 检查学生是否已被录取
        Application accepted = applicationMapper.selectAcceptedApplicationByStudentId(studentId);
        if (accepted == null)
        {
            return false;
        }

        // 检查是否有待处理的变更申请
        int pendingCount = topicChangeRequestMapper.checkStudentPendingRequest(studentId);
        return pendingCount == 0;
    }

    /**
     * 检查申请是否属于指定学生
     *
     * @param requestId 申请ID
     * @param studentId 学生ID
     * @return 是否拥有
     */
    @Override
    public boolean checkRequestOwner(Long requestId, Long studentId)
    {
        return topicChangeRequestMapper.checkRequestOwner(requestId, studentId) > 0;
    }

    /**
     * 检查申请的原教师是否为指定教师
     *
     * @param requestId 申请ID
     * @param teacherId 教师ID
     * @return 是否为原教师
     */
    @Override
    public boolean checkRequestOldTeacher(Long requestId, Long teacherId)
    {
        return topicChangeRequestMapper.checkRequestOldTeacher(requestId, teacherId) > 0;
    }

    /**
     * 检查申请的新教师是否为指定教师
     *
     * @param requestId 申请ID
     * @param teacherId 教师ID
     * @return 是否为新教师
     */
    @Override
    public boolean checkRequestNewTeacher(Long requestId, Long teacherId)
    {
        return topicChangeRequestMapper.checkRequestNewTeacher(requestId, teacherId) > 0;
    }
}